package com.lyxedu.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lyxedu.common.Constants;
import com.lyxedu.common.Result;
import com.lyxedu.controller.dto.UserDto;
import com.lyxedu.excption.ServiceException;
import com.lyxedu.mapper.RoleMenuMapper;
import com.lyxedu.pojo.Menu;
import com.lyxedu.pojo.Role;
import com.lyxedu.pojo.RoleMenu;
import com.lyxedu.services.MenuService;
import com.lyxedu.services.RoleService;
import com.lyxedu.services.UserService;
import com.lyxedu.pojo.User;
import com.lyxedu.utils.TokenUtils;
import io.swagger.models.auth.In;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    private UserService userService;
    @Resource
    private RoleService roleService;
    @Resource
    private RoleMenuMapper roleMenuMapper;
    @Resource
    private MenuService menuService;
    @GetMapping
    public Result list(){
        return Result.success(userService.list());
    }

    @PostMapping("/delete")
    public Result delete(int id){
        boolean b = userService.removeById(id);
        return Result.success();
    }

    @PostMapping("/delBatch")
    public Result delete(@RequestBody Integer[] ids){
        List<Integer> list = Arrays.asList(ids);
        boolean b = userService.removeByIds(list);
        return Result.success();
    }

    @GetMapping("/page")
    public Result page(int pageNum,int pageSize,User user){
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(User::getId);
        queryWrapper.like(user.getUsername()!=null&&user.getUsername()!="",User::getUsername,user.getUsername());
        queryWrapper.like(user.getAddress()!=null&&user.getAddress()!="",User::getAddress,user.getAddress());
        queryWrapper.like(user.getEmail()!=null&&user.getEmail()!="",User::getEmail,user.getEmail());
        Page<User> pageInfo = new Page<>(pageNum, pageSize);
        userService.page(pageInfo,queryWrapper);
        return Result.success(pageInfo);
    }


    @PostMapping("/save")
    public Result insert(@RequestBody User user){
        boolean b = userService.saveOrUpdateUser(user);
        return Result.success();

    }

    /**
     * 导出接口
     */
    @GetMapping("/export")
    public void export(HttpServletResponse response) throws Exception {
        // 从数据库查询出所有的数据
        List<User> list = userService.list();
        // 通过工具类创建writer 写出到磁盘路径
//        ExcelWriter writer = ExcelUtil.getWriter(filesUploadPath + "/用户信息.xlsx");
        // 在内存操作，写出到浏览器
        ExcelWriter writer = ExcelUtil.getWriter(true);
        //自定义标题别名
        writer.addHeaderAlias("username", "用户名");
        writer.addHeaderAlias("password", "密码");
        writer.addHeaderAlias("nickname", "昵称");
        writer.addHeaderAlias("email", "邮箱");
        writer.addHeaderAlias("phone", "电话");
        writer.addHeaderAlias("address", "地址");
        writer.addHeaderAlias("createTime", "创建时间");
        writer.addHeaderAlias("avatarUrl", "头像");

        // 一次性写出list内的对象到excel，使用默认样式，强制输出标题
        writer.write(list, true);

        // 设置浏览器响应的格式
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName = URLEncoder.encode("用户信息", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");

        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        out.close();
        writer.close();

    }


    /**
     * excel 导入
     * @param file
     * @throws Exception
     */
    @PostMapping("/import")
    public Result imp(MultipartFile file) throws Exception {
        InputStream inputStream = file.getInputStream();
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        // 方式1：(推荐) 通过 javabean的方式读取Excel内的对象，但是要求表头必须是英文，跟javabean的属性要对应起来
//        List<User> list = reader.readAll(User.class);

        // 方式2：忽略表头的中文，直接读取表的内容
        List<List<Object>> list = reader.read(1);
        List<User> users = CollUtil.newArrayList();
        for (List<Object> row : list) {
            User user = new User();
            user.setUsername(row.get(1).toString());
            user.setPassword(row.get(2).toString());
            user.setNickname(row.get(3).toString());
            user.setEmail(row.get(4).toString());
            user.setPhone(row.get(5).toString());
            user.setAddress(row.get(6).toString());
            user.setAvatarUrl(row.get(7).toString());
            users.add(user);
        }

        userService.saveBatch(users);
        return Result.success();
    }

    @GetMapping("/getUser")
    public Result getUserByName(String username){
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(username != null,User::getUsername,username);
        User user = userService.getOne(wrapper);
        return Result.success(user);
    }

    @PostMapping("/login")
    public Result login(@RequestBody UserDto userDto){
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(userDto.getUsername()!=null,User::getUsername,userDto.getUsername());
        User user = null;
        try {
            user = userService.getOne(wrapper);
        }catch (Exception e){
            throw new ServiceException(Constants.CODE_500, "系统错误");
        }
        if (user == null){
            return Result.error(Constants.CODE_500,"用户不存在");
        }
        if (!userDto.getPassword().equals(user.getPassword())){
            return Result.error(Constants.CODE_500,"账号或者密码错误");
        }
//        通过jwt生成token
        String token = TokenUtils.genToken(user.getId().toString(), user.getPassword());
        BeanUtils.copyProperties(user,userDto);
        userDto.setToken(token);
//        获取角色 在在查询拥有的权限
        String role = userDto.getRole();
        LambdaQueryWrapper<Role> roleWrapper = new LambdaQueryWrapper<>();
        roleWrapper.eq(Role::getFlag,role);
        Role roleOne = roleService.getOne(roleWrapper);
//        该角色所拥有的权限
        List<RoleMenu> roleMenus = roleMenuMapper.selectByIdList(roleOne.getId());
        List<Integer> ids = new ArrayList<>();
        for (RoleMenu roleMenu : roleMenus) {
            ids.add(roleMenu.getMenuId());
        }

//      查询所有权限
        List<Menu> list = (List<Menu>) menuService.roleMenus(1, 100, new Menu()).getData();
        List<Menu> menuList = new ArrayList<>();
        for (Menu menu : list) {

            if (ids.contains(menu.getId())){
                menuList.add(menu);
            }
            List<Menu> children = menu.getChildren();
            // removeIf()  移除 children 里面不在 menuIds集合中的 元素
            children.removeIf(child -> !ids.contains(child.getId()));
        }
        userDto.setMenuList(menuList);
        return Result.success(userDto);
    }

    @PostMapping("/logout")
    public Result logout(@RequestBody UserDto userDto){
        if (userDto.getUsername() != null){
            User data = (User) getUserByName(userDto.getUsername()).getData();
            if (data != null){
                return Result.error(Constants.CODE_500,"用户名已存在");
            }
            User user = new User();
            BeanUtils.copyProperties(userDto,user);
            boolean save = userService.save(user);
            return save?Result.success():Result.error(Constants.CODE_500,"注册失败");
        }
        return Result.error(Constants.CODE_400,"参数错误");
    }

}
